package com.thinkit.bigdata.core.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Stream;

/**
 *
 * Created by root on 16-9-30.
 */
public class DateFormatUtil {

    private static SimpleDateFormat sdf;

    public static String yyyy_MM_dd_HH_mm_ss = "yyyy-MM-dd HH:mm:ss";

    public static String yyyy_MM_dd = "yyyy-MM-dd";

    /**
     * 英文简写（默认）如：2010-12-01
     */
    public static String FORMAT_SHORT = "yyyy-MM-dd";
    /**
     * 英文全称  如：2010-12-01 23:15:06
     */
    public static String FORMAT_LONG = "yyyy-MM-dd HH:mm:ss";
    /**
     * 精确到毫秒的完整时间    如：yyyy-MM-dd HH:mm:ss.S
     */
    public static String FORMAT_FULL = "yyyy-MM-dd HH:mm:ss.S";
    /**
     * 中文简写  如：2010年12月01日
     */
    public static String FORMAT_SHORT_CN = "yyyy年MM月dd";
    /**
     * 中文全称  如：2010年12月01日  23时15分06秒
     */
    public static String FORMAT_LONG_CN = "yyyy年MM月dd日  HH时mm分ss秒";
    /**
     * 精确到毫秒的完整中文时间
     */
    public static String FORMAT_FULL_CN = "yyyy年MM月dd日  HH时mm分ss秒SSS毫秒";



    // a double to xx:xx:xx
    public static String secToTime(double time) {
        String timeStr;
        int hour;
        int minute;
        int second;
        if (time <= 0)
            return "00:00";
        else {
            minute = (int) (time / 60);
            if (minute < 60) {
                second = (int) (time % 60);
                timeStr = unitFormat(minute) + ":" + unitFormat(second);
            } else {
                hour = minute / 60;
//                if (hour > 99)
//                    return "99:59:59";
                minute = minute % 60;
                second = (int) (time - hour * 3600 - minute * 60);
                timeStr = unitFormat(hour) + ":" + unitFormat(minute) + ":" + unitFormat(second);
            }
        }
        return timeStr;
    }

    private static String unitFormat(double i) {
        String retStr;
        if (i >= 0 && i < 10)
            retStr = "0" + Double.toString(i);
        else
            retStr = "" + i;
        return retStr.split("\\.")[0];
    }

    public static Date Str2Date(String str) {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            date = sdf.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 自定义转换格式
     * @param str -
     * @param type -
     * @return -
     */
    public static Date Str2Date(String str, String type) {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat(type);
        try {
            date = sdf.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    public static Date StrToDate(String str) {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        try {
            date = sdf.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    public static String DateToStr(Date date) {

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String str = format.format(date);
        return str;
    }

    /**
     * 自定义格式
     * @param date -
     * @param type -
     * @return -
     */
    public static String DateToStr(Date date, String type) {

        SimpleDateFormat format = new SimpleDateFormat(type);
        String str = format.format(date);
        return str;
    }

    /**
     * 获取当前时间 格式：yyyy-MM-dd HH:mm:ss.SSSZ
     *
     * @return -
     */
    public static String getCurrentDataTime() {
        sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSZ");
        return sdf.format(new Date());
    }

    /**
     * 获取当前时间 格式：yyyyMMddHHmmssSSS
     *
     * @return -
     */
    public static String getNowTime() {
        sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        return sdf.format(new Date());
    }

    /**
     * 获取当前时间 格式：yyyy-MM-dd HH:mm:ss
     *
     * @return -
     */
    public static String getNowDataTime() {
        sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(new Date());
    }

    /**
     * 获取当前时间 格式：yyyy-MM-dd
     *
     * @return -
     */
    public static String getData() {
        sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(new Date());
    }

    /**
     *
     * @param date -
     * @return -
     */
    public static String getData(Date date) {
        sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(date);
    }

    /**
     *
     * @return -
     */
    public static long getDataTime() {
        Date date = new Date();
        return date.getTime();
    }

    /**
     *
     * @return -
     */
    public static long getDataTime(Date date) {
        return date.getTime();
    }

    /**
     * 获取当前时间 格式：HH:mm:ss
     *
     * @return -
     */
    public static String getTime() {
        sdf = new SimpleDateFormat("HH:mm:ss");
        return sdf.format(new Date());
    }

    /**
     * 根据format获取时间格式,format不能为空
     *
     * @param format -
     * @param date -
     * @return -
     */
    public static String getTime(String format, Date date) {
        if (date == null || format == null) return "";
        sdf = new SimpleDateFormat(format);
        return sdf.format(date);
    }

    /**
     * 获取当前时间 格式：yyyy-MM-dd HH:mm:ss.SSSZ
     *
     * @return -
     */
    public static String formatDate(Date data) {
        sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSZ");
        return sdf.format(data);
    }

    /**
     * 将字符型转换为指定格式日期型
     *
     * @param _date  需要转换成日期的字符串
     * @param format 与需要转换成日期的字符串相匹配的格式
     * @return -
     */
    public static Date stringToDate(String _date, String format) {
        if (null == format || "".equals(format)) {
            format = "yyyy-MM-dd HH:mm:ss";
        }
        sdf = new SimpleDateFormat(format);
        Date date = null;
        try {
            date = sdf.parse(_date);
        } catch (ParseException e) {
            // TODOAuto-generated catch block
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 将日期型转换为指定格式的字符串
     *
     * @param date   日期
     * @param format 格式
     * @return -
     */
    public static String dateToString(Date date, String format) {
        if (null == format || "".equals(format)) {
            format = "yyyy年MM月dd日 hh点:mm分:ss秒";
        }
        sdf = new SimpleDateFormat(format);
        if (date == null)
            return "";
        return sdf.format(date);
    }

    /**
     * 获取时间戳 10位
     *
     * @return -
     */
    public static String getCreateTime() {
        Date date = new Date();
        long time = date.getTime();

        String dateline = time + "";
        dateline = dateline.substring(0, 10);
        return dateline;
    }

    /**
     * 处理增加一秒的问题
     * @param date -
     * @return -
     */
    public static Date getAppointDayOfEndTime(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }

    /**
     * 获取当前时间
     */
    public static String getTimeString() {
        SimpleDateFormat df = new SimpleDateFormat(FORMAT_FULL);
        Calendar calendar = Calendar.getInstance();
        return df.format(calendar.getTime());
    }

    /**
     * 获取日期年份
     * @param date 日期
     * @return
     */
    public static String getYear(Date date) {
        SimpleDateFormat df = new SimpleDateFormat(FORMAT_LONG);
        return df.format(date).substring(0, 4);
    }
    /**
     * 功能描述：返回月
     *
     * @param date
     *            Date 日期
     * @return 返回月份
     */
    public static int getMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MONTH) + 1;
    }

    /**
     * 功能描述：返回日期
     *
     * @param date
     *            Date 日期
     * @return 返回日份
     */
    public static int getDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_MONTH);
    }

    /**
     * 功能描述：返回小时
     *
     * @param date
     *            日期
     * @return 返回小时
     */
    public static int getHour(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.HOUR_OF_DAY);
    }

    /**
     * 功能描述：返回分
     *
     * @param date
     *            日期
     * @return 返回分钟
     */
    public static int getMinute(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MINUTE);
    }

    /**
     * 返回秒钟
     *
     * @param date
     *            Date 日期
     * @return 返回秒钟
     */
    public static int getSecond(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.SECOND);
    }

    /**
     * 功能描述：返回毫
     *
     * @param date
     *            日期
     * @return 返回毫
     */
    public static long getMillis(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.getTimeInMillis();
    }


    /**
     * 判断是否为今天
     *
     * @param date -
     * @return -
     */
    public static boolean isToday(Date date) {
        if (date == null) {
            return false;
        } else {
            Calendar appoint = Calendar.getInstance();
            appoint.setTime(date);
            Calendar toDay = Calendar.getInstance();
            if (toDay.get(Calendar.YEAR) == appoint.get(Calendar.YEAR)
                    && toDay.get(Calendar.MONTH) == appoint.get(Calendar.MONTH)
                    && toDay.get(Calendar.DAY_OF_MONTH) == appoint.get(Calendar.DAY_OF_MONTH)) {
                return true;
            } else {
                return false;
            }
        }
    }

    /**
     * 增加几天
     *
     * @param date -
     * @param days -
     * @return -
     */
    public static Date addNDay(Date date, int days) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, days);
        return calendar.getTime();
    }

    /**
     * 增加几月
     *
     * @param date -
     * @param months -
     * @return -
     */
    public static Date addMonth(Date date, int months) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, months);
        return calendar.getTime();
    }

    /**
     * 相差秒
     *
     * @param date1 -
     * @param date2 -
     * @return -
     */
    public static int intervalSecond(Date date1, Date date2) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date1);
        long time1 = cal.getTimeInMillis();
        cal.setTime(date2);
        long time2 = cal.getTimeInMillis();

        return Integer.parseInt(String.valueOf((time2 - time1) / (1000)));
    }

    /**
     * 相差分钟数
     *
     * @param date1 -
     * @param date2 -
     * @return -
     */
    public static int intervalMin(Date date1, Date date2) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date1);
        long time1 = cal.getTimeInMillis();
        cal.setTime(date2);
        long time2 = cal.getTimeInMillis();
        return Integer.parseInt(String.valueOf((time2 - time1) / (1000 * 60)));
    }

    /**
     * 相差几天
     *
     * @param date1 -
     * @param date2 -
     * @return -
     */
    public static int intervalDay(Date date1, Date date2) {

        Calendar cal = Calendar.getInstance();
        cal.setTime(date1);
        long time1 = cal.getTimeInMillis();
        cal.setTime(date2);
        long time2 = cal.getTimeInMillis();
        return Integer.parseInt(String.valueOf((time2 - time1) / (1000 * 3600 * 24)));
    }

    /**
     * 相差几周
     *
     * @param date1 -
     * @param date2 -
     * @return -
     */
    public static int intervalWeek(Date date1, Date date2) {
        int days = intervalDay(date1, date2);
        return days / 7;
    }

    /**
     * 相差月数
     *
     * @param date1 -
     * @param date2 -
     * @return -
     */
    public static int intervalMonth(Date date1, Date date2) {
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();

        c1.setTime(date1);
        c2.setTime(date2);

        int year = c2.get(Calendar.YEAR) - c1.get(Calendar.YEAR);
        int month = c2.get(Calendar.MONTH) - c1.get(Calendar.MONTH);

        return year * 12 + month;
    }

    /**
     * 相差年数
     *
     * @param date1 -
     * @param date2 -
     * @return -
     */
    public static int intervalYear(Date date1, Date date2) {
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(date1);
        c2.setTime(date2);
        return c2.get(Calendar.YEAR) - c1.get(Calendar.YEAR);
    }

    /**
     * 当前时间 加/减  分钟
     *
     * @param date -
     * @param minute -
     * @return -
     */
    public static Date addMinute(Date date, int minute) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MINUTE, minute);
        return c.getTime();
    }

    //addType:添加的日期类型：Calendar.YEAR、Calendar.MONTH等
    //addNum:添加的日期间隔：正数为+，负数为-
    public static String getAddTimeStr(int addType, int addNum) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(addType, calendar.get(addType) + addNum);
        Date now = calendar.getTime();
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return format.format(now);
    }

    //验证字符串是否为"yyyy-MM-dd"格式
    public static boolean isyyyyMMdd(String dateStr) {
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        if (dateStr.length() != 10) {
            return false;
        } else {
            try {
                Date date = format.parse(dateStr);
            } catch (ParseException e) {
                return false;
            }
        }
        return true;
    }

    public static String getFirst() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        //获取当前月第一天：
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, 0);
        c.set(Calendar.DAY_OF_MONTH,1);//设置为1号,当前日期既为本月第一天
        String first = format.format(c.getTime());
        System.out.println("===============first:"+first);
        return first;
    }

    public static String getLast() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        //获取当前月最后一天
        Calendar ca = Calendar.getInstance();
        ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
        String last = format.format(ca.getTime());
        System.out.println("===============last:"+last);
        return last;
    }

    /**
     * 获取两个日期间隔的所有日期
     * @param start 格式必须为'2018-01-25'
     * @param end 格式必须为'2018-01-25'
     * @return -
     */
    public static List<String> getBetweenDate(String start, String end){
        List<String> list = new ArrayList<>();
        LocalDate startDate = LocalDate.parse(start);
        LocalDate endDate = LocalDate.parse(end);

        long distance = ChronoUnit.DAYS.between(startDate, endDate);
        if (distance < 1) {
            return list;
        }
        Stream.iterate(startDate, d -> d.plusDays(1)).limit(distance + 1).forEach(f -> list.add(f.toString()));
        return list;
    }

    public static void main(String[] args) {
//        System.out.println(intervalDay(stringToDate("2018-01-18", yyyy_MM_dd), stringToDate("2019-03-01", yyyy_MM_dd)));


//        System.out.println(dateToString(new Date(), DateFormatUtil.yyyy_MM_dd_HH_mm_ss));


//        System.out.println(dateToString(getAppointDayOfEndTime(new Date()), DateFormatUtil.yyyy_MM_dd_HH_mm_ss));

//        List<String> list = getBetweenDate("2019-10-01", "2019-10-04");

        //在Java8中的遍历方式
//        list.forEach(System.out::println);

        getBetweenDate("2019-10-01", "2019-10-04").forEach(System.out::println);
    }

}
